package com.power.sifa.approve.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.plf.common.domain.PageDataResponse;
import com.plf.common.domain.ResponseDTO;
import com.plf.common.domain.YesNo;
import com.plf.common.file.model.FileVo;
import com.plf.common.utils.ExcelUtil;
import com.plf.common.utils.SpringHolder;
import com.plf.core.common.file.FileController;
import com.power.sifa.approve.service.Apl_archiveService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.power.sifa.approve.model.Apl_dossier;
import com.power.sifa.approve.model.pageInfo.Apl_dossierPageInfo;
import com.power.sifa.approve.api.IApl_dossierFeign;
import com.power.sifa.approve.service.Apl_dossierService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;



/**
 *   电子卷宗控制器
 */

@Slf4j
//@PowerLog
@RestController
@Api(value = "Apl_dossierController",tags={"电子卷宗"})
public class Apl_dossierController implements IApl_dossierFeign{

    @Resource
    private Apl_dossierService apl_dossierService;

    @Resource
    private Apl_archiveService apl_archiveService;


    @Override
    @ApiOperation("查询电子卷宗分页列表")
    @SaCheckPermission("apl_dossier_list")
    public ResponseDTO list(Apl_dossierPageInfo pageInfo) {
        Assert.notNull(pageInfo, "pageInfo参数不能为空");
        Page<Apl_dossier> page = this.apl_dossierService.findAll(pageInfo);
        List list = new ArrayList();
        if (!page.isEmpty()) {
            for (Apl_dossier apl_dossier : page) {
                apl_dossier.geneText();
                list.add(apl_dossier);
            }
        }
        PageDataResponse p = new PageDataResponse(list, page.getTotalElements(), page.getSize(), pageInfo.getPageNumber()<=1 ? 1 : pageInfo.getPageNumber());
        return ResponseDTO.succData(p);
    }

    @Override
    @ApiOperation("查看电子卷宗")
    @SaCheckPermission("apl_dossier_view")
    public ResponseDTO view(String id) {
        Assert.notNull(id, "id不能为空");
        Apl_dossier apl_dossier  = apl_dossierService.getById(id);
        if (apl_dossier != null) {
            apl_dossier.geneText();
        }
        return ResponseDTO.succData(apl_dossier);
    }

    @Override
    @ApiOperation("删除电子卷宗")
    @SaCheckPermission("apl_dossier_del")
    public ResponseDTO delete(String id) {
        Assert.notNull(id, "id不能为空");
        apl_dossierService.removeById(id);
        return ResponseDTO.succ();
    }

    @Override
    @ApiOperation("保存或修改电子卷宗")
    @SaCheckPermission("apl_dossier_save")
    public ResponseDTO save(Apl_dossier apl_dossier) {
        Assert.notNull(apl_dossier, "apl_dossier不能为空");
        apl_dossierService.saveOrUpdate(apl_dossier);
        return ResponseDTO.succ();
    }

    @Override
    @ApiOperation(value="批量删除电子卷宗")
    @SaCheckPermission("apl_dossier_del")
    public ResponseDTO batchDel(String ids) {
        Assert.isTrue(StringUtils.hasText(ids), "ids不能为空");
        List<Integer> list = Arrays.asList(ids.split(",")).stream().map(s -> Integer.parseInt(s.trim())).collect(Collectors.toList());
        apl_dossierService.removeByIds(list);
        return ResponseDTO.succ();
    }

    @Override
    @ApiOperation(value="导出excel")
    @SaCheckPermission("apl_dossier_list")
    public void output(HttpServletResponse response, Apl_dossierPageInfo pageInfo) {
        Assert.notNull(pageInfo, "pageInfo不能为空");
        String title = "电子卷宗";
        String[] heads = {"applyid + nanoid","applyid","节点名称","节点类型","顺序","材料id","删除标识","父级id","过程材料类型"};
        String[] fields = {"id","applyid","name","type","sort","matid","deleted","parentid","mattype"};
        Page<Apl_dossier> page = this.apl_dossierService.findAll(pageInfo);
        ExcelUtil.exportXls(title, heads, fields, page.getContent(), response);
    }

    @Override
    @ApiOperation(value="导出excel模板")
    public void exportExcelTemplate(HttpServletResponse response) {
        String title = "电子卷宗";
        //id自增或list从表可自行删除，需与导入项一致
        String[] heads = {"applyid + nanoid","applyid","节点名称","节点类型","顺序","材料id","删除标识","父级id","过程材料类型"};
        ExcelUtil.exportXls(title, heads, null, null, response);
    }

	@Override
	@ApiOperation(value="导入excel")
	public ResponseDTO importExcel(MultipartFile file) throws IOException {

        Assert.notNull(file, "file不能为空");
        //id自增或list从表可自行删除，需与下载的模板中导入项一致
        String[] fields = {"id","applyid","name","type","sort","matid","deleted","parentid","mattype"};
        List<Apl_dossier> list = (List<Apl_dossier>)ExcelUtil.Import(fields, file, Apl_dossier.class);
        if(!CollectionUtils.isEmpty(list)) {
            this.apl_dossierService.saveAll(list);
        }
        return ResponseDTO.succ();
	}

    /**
     * 通过applyid查询对应的电子卷宗文件树形结构
     * @param applyid applyid
     * @param isEdit 是否是编辑模式
     * @return
     */
    @Override
    public ResponseDTO getDocTreeByApplyid(String applyid, Boolean isEdit, Integer serviceType) {
        // 调用默认的更新方法
        if (isEdit) {
            this.apl_dossierService.updateDossier(applyid, serviceType);
        }
        List<Apl_dossier> dossierList = this.apl_dossierService.getDocTreeListByApplyid(applyid);
        if (CollectionUtil.isEmpty(dossierList)) {
            if (isEdit) {
                // 编辑模式已经更新过一次卷宗树形结构
                return ResponseDTO.wrap(500, "当前节点数据为空");
            }
            // 重新更新一次数据再次查询
            this.apl_dossierService.updateDossier(applyid, serviceType);
            dossierList = this.apl_dossierService.getDocTreeListByApplyid(applyid);
            if (CollectionUtil.isEmpty(dossierList)) {
                return ResponseDTO.wrap(500, "当前节点数据为空");
            }
        }
        return ResponseDTO.succData(this.apl_dossierService.formateTreeStruct(dossierList));
    }

    /**
     * 删除树节点及下属的子层级节点
     * @param treeNodeId
     * @return
     */
    @Override
    public ResponseDTO deleteTreeNode(String treeNodeId) {
        Assert.notNull(treeNodeId, "节点id不能为空");
        try {
            this.apl_dossierService.deleteTreeNode(treeNodeId);
            return ResponseDTO.succ();
        } catch (Exception e) {
            return ResponseDTO.wrap(500, "删除节点失败");
        }
    }

    /**
     * 新增层级节点数据，
     * @param treeNodeType 节点类型
     * @param treeNodeName 节点名称
     * @param parentId 父节点id
     * @return
     */
    @Override
    public ResponseDTO addTreeNode(Integer treeNodeType, String treeNodeName, String parentId) {
        Assert.notNull(treeNodeType, "节点类型不能为空");
        Assert.notNull(treeNodeName, "节点名称不能为空");
        Assert.notNull(parentId, "父节点id不能为空");
        try {
            Apl_dossier dossier = this.apl_dossierService.addTreeNode(treeNodeType,treeNodeName, parentId);
            return ResponseDTO.succData(dossier);
        } catch (Exception e) {
            return ResponseDTO.wrap(500, "新增节点失败");
        }
    }
    /**
     * 新增根节点数据，
     * @param applyid
     * @param treeNodeName
     * @return
     */
    @Override
    public ResponseDTO addRootTreeNode(String applyid, String treeNodeName, String parentId) {
        Assert.notNull(applyid, "applyid不能为空");
        Assert.notNull(treeNodeName, "节点名称不能为空");
        Assert.notNull(parentId, "parentId不能为空");
        try {
            Apl_dossier dossier = this.apl_dossierService.addRootTreeNode(applyid, treeNodeName, parentId);
            return ResponseDTO.succData(dossier);
        } catch (Exception e) {
            return ResponseDTO.wrap(500, "新增节点失败");
        }
    }

    /**
     * 保存材料
     * @param applyid
     * @param parentId
     * @param materialId
     * @param materialName
     * @param deleted
     * @param mattype
     * @return
     */
    @Override
    public ResponseDTO saveMaterialToTree(String applyid, String parentId, String materialId, String materialName, Integer deleted, String mattype) {
        Assert.notNull(applyid, "applyid不能为空");
        Assert.notNull(parentId, "parentId不能为空");
        Assert.notNull(materialId, "materialId不能为空");
        Assert.notNull(materialName, "materialName不能为空");
        try {
            Apl_dossier dossier = this.apl_dossierService.saveMaterialToTree(applyid, parentId,materialId,
                    materialName,deleted,mattype);
            return ResponseDTO.succData(dossier);
        } catch (Exception e) {
            return ResponseDTO.wrap(500, "新增节点失败");
        }
    }


    @Override
    public ResponseDTO saveNoStoreMaterialToTree(List<MultipartFile> files, String applyid, String parentId) {
        Assert.notNull(files, "files不能为空");
        Assert.notNull(applyid, "applyid不能为空");
        Assert.notNull(parentId, "parentId不能为空");
        FileController fileController = SpringHolder.getBean(FileController.class);
        try {
            // 获取保存的数据，将其保存的对应的数据库里
            ResponseDTO<List> result = fileController.minioUpload(files, null, null);
            List<Apl_dossier> saveResult = new ArrayList<>();
            if (ObjectUtil.isNotEmpty(result) && result.getCode() == ResponseDTO.succ().getCode()) {
                List<FileVo> fileDataList = result.getData();
                if (CollectionUtil.isNotEmpty(fileDataList)) {
                    fileDataList.stream().forEach(fileData -> {
                        if (ObjectUtil.isNotNull(fileData)) {
                            try {
                                String materialId = fileData.getId();
                                String materialName = fileData.getFilename();
                                Apl_dossier dossier = this.apl_dossierService.saveMaterialToTree(applyid, parentId, materialId,
                                        materialName, YesNo.YES, null);
                                saveResult.add(dossier);
                            } catch (Exception e) {
                                log.error("树结构对象保存异常:{}", e.getMessage());
                            }
                        }
                    });
                }
                return ResponseDTO.succData(saveResult);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("文件保存异常:{}", e.getMessage());
            return ResponseDTO.wrap(500, "文件保存异常");
        }
        return ResponseDTO.succ();
    }


    /**
     * 更新节点名称
     * @param treeNodeId
     * @param treeNodeName
     * @return
     */
    @Override
    public ResponseDTO updateTreeNodeName( String treeNodeId, String treeNodeName) {
        Assert.notNull(treeNodeId, "节点id不能为空");
        Assert.notNull(treeNodeName, "节点名称不能为空");
        Apl_dossier dossier = this.apl_dossierService.updateTreeNodeName(treeNodeId,treeNodeName);
        return ResponseDTO.succData(dossier);
    }

    /**
     * 重新更新目录页码序号
     * @param applyid
     * @return
     */
    @Override
    public ResponseDTO updateTreeNodeIndex(String applyid) {
        Assert.notNull(applyid, "applyid不能为空");
        // 更新目录页码数据
        this.apl_dossierService.updateTreeIndex(applyid);
        List<Apl_dossier> dossierList = this.apl_dossierService.getDocTreeListByApplyid(applyid);
        if (CollectionUtil.isEmpty(dossierList)) {
            return ResponseDTO.wrap(500, "当前节点数据为空");
        }
        return ResponseDTO.succData(this.apl_dossierService.formateTreeStruct(dossierList));
    }

    /**
     * 案件归档接口
     * @param applyid
     * @return
     */
    @Override
    public ResponseDTO recordCase(String applyid, String userId, String userName, Integer serviceType) {
        Assert.notNull(applyid, "applyid不能为空");
        // 更新目录页码数据
        try {
            this.apl_dossierService.recordCase(applyid, userId, userName, serviceType);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("案件归档失败:{}", e.getMessage());
            return ResponseDTO.wrap(500, "案件归档失败");
        }
        return ResponseDTO.succ();
    }

    @Override
    public ResponseDTO regenerateDocTree(String applyid) {
        Assert.notNull(applyid, "applyid不能为空");
        // 更新目录页码数据
        try {
            // 6.1 初始化归档首页数据
            this.apl_archiveService.initialArchiveData(applyid);
            // 6.2 初始化归档电子卷宗数据
            this.apl_dossierService.buildInitDossier(applyid);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("重新生成文件目录失败:{}", e.getMessage());
            return ResponseDTO.wrap(500, "重新生成文件目录失败");
        }
        return ResponseDTO.succ();
    }

    @Override
    public ResponseDTO regenerateSuperviseDocTree(String applyid) {
        Assert.notNull(applyid, "applyid不能为空");
        // 更新目录页码数据
        try {
            // 6.1 初始化归档首页数据
            this.apl_archiveService.initialSuperviseArchiveData(applyid);
            // 5.1 初始化归档电子卷宗数据
            this.apl_dossierService.buildInitSuperviseDossier(applyid);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("重新生成文件目录失败:{}", e.getMessage());
            return ResponseDTO.wrap(500, "重新生成文件目录失败");
        }
        return ResponseDTO.succ();
    }


}
